package io.afu.baseframework.asserts;

import io.afu.baseframework.enums.ConstantEnum;
import io.afu.baseframework.enums.ErrEnum;
import io.afu.baseframework.exceptions.BaseException;

/**
 * @author RffanLAB.方露宇
 * @version 0.1
 */
public class AssertHelper {

    /**
     * 断言对象不为空字符串
     * @param str 输入字符串
     * @param message 抛错的消息
     * @throws BaseException 错误
     */
    public static void NotEmptyString(String str,String message) throws BaseException {
        if (str == null || str.isEmpty()) {
            throw new BaseException(message);
        }
    }

    /**
     * 断言对象不为空字符串
     * @param str 输入字符串
     * @param errEnum 抛错的消息
     * @throws BaseException 错误
     */
    public static void NotEmptyString(String str, ErrEnum errEnum) throws BaseException {
        if (str == null || str.isEmpty()) {
            throw new BaseException(errEnum);
        }
    }


    /**
     * 断言不为空，为空则返回msg
     * @param obj 需要断言的对象
     * @param msg 为空后抛出的消息
     * @throws BaseException 抛出的错误类型
     */
    public static void NotNull(Object obj, String msg) throws BaseException {
        if (obj == null) {
            throw new BaseException(msg);
        }
    }

    /**
     * 断言不为空，为空则返回msg
     * @param obj 需要断言的对象
     * @param errEnum 为空后抛出的消息
     * @throws BaseException 抛出的错误类型
     */
    public static void NotNull(Object obj, ErrEnum errEnum) throws BaseException {
        if (obj == null) {
            throw new BaseException(errEnum);
        }
    }

    /**
     * 断言对象属性不为空，为空则返回msg
     * @param obj 需要判断对象
     * @param feild 属性名
     * @param msg 为空后抛出的消息
     * @throws BaseException 抛出的错误类型
     */
    public static void FeildNotNull(Object obj,String feild, String msg) throws BaseException {
        try {
            if (obj.getClass().getDeclaredField(feild).get(obj) == null) {
                throw new BaseException(msg);
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new BaseException("需要空判的对象属性不存在");
        }catch (Exception e) {
            throw new BaseException(msg);
        }
    }

    /**
     * 断言对象属性不为空，为空则返回msg
     * @param obj 需要判断对象
     * @param feild 属性名
     * @param errEnum 为空后抛出的消息
     * @throws BaseException 抛出的错误类型
     */
    public static void FeildNotNull(Object obj,String feild,ErrEnum errEnum) throws BaseException {
        try {
            if (obj.getClass().getDeclaredField(feild).get(obj) == null) {
                throw new BaseException(errEnum);
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new BaseException("需要空判的对象属性不存在");
        }catch (Exception e) {
            throw new BaseException(errEnum);
        }
    }

    /**
     * 判断入参仅仅在列表单中。
     * @param arr 列表
     * @param target 需要判断的对象
     * @param msg 出错后抛出的消息
     * @param <T> 泛型
     * @throws BaseException 抛出的错误类型
     */
    public static <T> void OnlyContains(T[] arr, T target, String msg) throws BaseException {
        OnlyContains(arr, target, msg, false);
    }

    /**
     * 判断入参仅仅在列表单中。
     * @param arr 列表
     * @param target 需要判断的对象
     * @param errEnum 出错后抛出的消息
     * @param <T> 泛型
     * @throws BaseException 抛出的错误类型
     */
    public static <T> void OnlyContains(T[] arr, T target, ErrEnum errEnum) throws BaseException {
        OnlyContains(arr, target, errEnum, false);
    }

    /**
     * 判断入参仅仅在列表单中。
     * @param arr 列表
     * @param target 需要判断的对象
     * @param msg 出错后抛出的消息
     * @param allowNull 是否允许为空
     * @param <T> 泛型
     * @throws BaseException 抛出的错误类型
     */
    public static <T> void OnlyContains(T[] arr, T target, String msg,boolean allowNull) throws BaseException {
        // 判断对象是否允许为空，允许为空，如果为空则不进行判断了。
        if (!allowNull){
            NotNull(target, msg);
        }else {
            if (target == null) {
                return;
            }
        }
        boolean flag = false;
        for (T t : arr) {
            if (t.equals(target)) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            throw new BaseException(msg);
        }
    }


    /**
     * 判断入参仅仅在列表单中。
     * @param arr 列表
     * @param target 需要判断的对象
     * @param errEnum 出错后抛出的消息
     * @param allowNull 是否允许为空
     * @param <T> 泛型
     * @throws BaseException 抛出的错误类型
     */
    public static <T> void OnlyContains(T[] arr, T target, ErrEnum errEnum,boolean allowNull) throws BaseException {
        // 判断对象是否允许为空，允许为空，如果为空则不进行判断了。
        if (!allowNull){
            NotNull(target, errEnum);
        }else {
            if (target == null) {
                return;
            }
        }
        boolean flag = false;
        for (T t : arr) {
            if (t.equals(target)) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            throw new BaseException(errEnum);
        }
    }


    /**
     * 判断对象内的属性仅仅包含某些值
     * @param obj 需要判断的对象
     * @param feild 属性名
     * @param values 允许的值
     * @param errEnum 不在允许范围内的消息
     * @param <T> 属性类型
     * @throws BaseException 抛出的错误类型
     */
    public static <T> void  FieldOnlyContains(Object obj,String feild, T[] values, ErrEnum errEnum) throws BaseException {
        try {
            T value = (T) obj.getClass().getDeclaredField(feild).get(obj);
            for (T v : values) {
                if (v.equals(value)) {
                    return;
                }
            }
            throw new BaseException(errEnum);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new BaseException("需要空判的对象属性不存在");
        }catch (Exception e) {
            throw new BaseException(errEnum);
        }
    }

    /**
     * 断言最大值，超过最大值则返回错误消息
     * @param number 需要判断的值
     * @param max 最大值
     * @param msg 错误消息
     * @throws BaseException 抛错类型
     */
    public static void MaxNumber(Integer number, Integer max, String msg) throws BaseException {
        // 优先进行空判。否则比较将会出错。 默认认为第二个传入的参数不会为空。第二个传入参数可控。
        NotNull(number, msg);
        if (number > max) {
            throw new BaseException(msg);
        }
    }

    /**
     * 断言最大值，超过最大值则返回错误消息
     * @param number 需要判断的值
     * @param max 最大值
     * @param errEnum 错误消息
     * @throws BaseException 抛错类型
     */
    public static void MaxNumber(Integer number, Integer max, ErrEnum errEnum) throws BaseException {
        // 优先进行空判。否则比较将会出错。 默认认为第二个传入的参数不会为空。第二个传入参数可控。
        NotNull(number, errEnum);
        if (number > max) {
            throw new BaseException(errEnum);
        }
    }

    /**
     * 断言最小值，小于最小值则返回错误消息
     * @param number 需要判断的值
     * @param min 最小值
     * @param msg 错误消息
     * @throws BaseException 抛错类型
     */
    public static void MinNumber(Integer number, Integer min, String msg) throws BaseException {
        // 优先进行空判。否则比较将会出错。 默认认为第二个传入的参数不会为空。第二个传入参数可控。
        NotNull(number, msg);
        if (number < min) {
            throw new BaseException(msg);
        }
    }

    /**
     * 断言最小值，小于最小值则返回错误消息
     * @param number 需要判断的值
     * @param min 最小值
     * @param errEnum 错误消息
     * @throws BaseException 抛错类型
     */
    public static void MinNumber(Integer number, Integer min,ErrEnum errEnum) throws BaseException {
        // 优先进行空判。否则比较将会出错。 默认认为第二个传入的参数不会为空。第二个传入参数可控。
        NotNull(number, errEnum);
        if (number < min) {
            throw new BaseException(errEnum);
        }
    }




}
